package com.whales.shared.interceptor;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.ModelAndViewDefiningException;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * @클래스명 : LoginCheckInterceptor   
 * @작성자 : sw775.park
 * @작성일 : May 12, 2009     
 * @설명 : Login Check를 위한 Handler Interceptor 
 * @수정이력 - 수정일,수정자,수정내용  					   
 * 
 */
public class LoginCheckInterceptor extends HandlerInterceptorAdapter {

    /**
     * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
     * @메소드명 : preHandle  					   
     * @작성자 : sw775.park
     * @작성일 : May 12, 2009
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     * @설명 : Controller를 호출하기 전에 Login 유무를 체크 한다.
     * @수정이력 - 수정일,수정자,수정내용					   
     *
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        // locale 설정
        // 부라우저의 언어 설정으로 변경되므로 실시간으로 변경되어야 한다.
        session.setAttribute("userLocale", request.getLocale().getLanguage());
        // 특정 사용자의 Login 반복 현상을 방지하기 위한 P3P 해더를 셋팅한다.
        // 이유는 특정 사용자 중 내부 Iframe을 cross domain으로 인식하는 문제로 인해
        // iframe내에 sessionid를 신규로 생성한다. 이는 쿠키에 저장된 sessionid를 공유하지 못해 발생된 문제로 파악된다.
        response.setHeader("P3P", "CP='CAO PSA CONi OTR OUR DEM ONL'");
        return isLogined(request, response);
    }

    /**
     * Login유무 체크
     * @메소드명 : isLogined   					   
     * @작성자 : sw775.park   
     * @작성일 : 2012. 3. 5.
     * @param request
     * @param response
     * @return
     * @throws Exception	
     * @설명 :
     * @수정이력 - 수정일,수정자,수정내용					   
     *										   
     */
    private boolean isLogined(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        // URL 정보
        String uri = request.getRequestURI();
        // URL Query 정보
        String qryString = request.getQueryString();
        // URL Full 정보
        String sInitUrl = uri + ((qryString != null)?"?" + qryString : "");
        // Request Type 중 x-requested-with header 정보
        String requestType = request.getHeader("x-requested-with");
        // login 세션이 유무에 따라 Login 체크를 한다.
        if (session.getAttribute("login") == null) {
            if (this.isExcludeUrl(request)) {// login controller를 호출하면 그냥 통과
                return true;
            } else if (!this.isExcludeUrl(request) && requestType == null) { // 기타 url인 경우 login 페이지로 redirection
                session.setAttribute("DirectAccessRequestUrl", sInitUrl);
                throw new ModelAndViewDefiningException(new ModelAndView("redirect:/login.do"));
            } else if (!this.isExcludeUrl(request) && requestType != null && requestType.equals("XMLHttpRequest")) { // Request Type이 Ajax call인 경우
                response.setStatus(500);
                response.setContentType("text/html;charset=UTF-8");
                PrintWriter printWriter = response.getWriter();
                printWriter.println("세션이 종료되었습니다.\n\n 다시 로그인 해 주세요");
                printWriter.flush();
                return false;
            }
        }
        return true;
    }
    
    /**
     * 로그인 체크에 예외되는 URL인지 체크 
     * @메소드명 : isExcludeUrl   					   
     * @작성자 : sw775.park   
     * @작성일 : 2012. 3. 5.
     * @param request
     * @return	
     * @설명 :
     * @수정이력 - 수정일,수정자,수정내용					   
     *										   
     */
    private boolean isExcludeUrl(HttpServletRequest request){
        // URL 정보
        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();
        if(uri.equals(contextPath + "/login.do") 
        		|| uri.equals(contextPath + "/checkLogin.do")
        		|| uri.equals(contextPath + "/software/getVersion.do")
        		|| uri.equals(contextPath + "/fault/create.do")
        		|| uri.equals(contextPath + "/pc/updatePcTime.do")
        		){
            return true;
        }
        return false;
    }
}
